package tech.shupi.babytaptv

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
import android.util.Log
import java.net.*
import java.io.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import org.json.JSONObject
import java.nio.ByteBuffer
import java.nio.ByteOrder

class UDPDiscoveryModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    companion object {
        private const val TAG = "UDPDiscovery"
        private const val UDP_DISCOVERY_PORT = 8554
        private const val MAGIC = 0x2EA7D90B
    }

    private var socket: DatagramSocket? = null
    private var isRunning = AtomicBoolean(false)

    override fun getName(): String {
        return "UDPDiscoveryModule"
    }

    @ReactMethod
    fun startDiscovery(promise: Promise) {
        try {
            // 先停止之前的监听
            if (isRunning.get()) {
                Log.i(TAG, "Stopping previous discovery before starting new one")
                stopDiscoveryInternal()
            }

            // 创建 UDP socket，监听端口 8554
            socket = DatagramSocket(UDP_DISCOVERY_PORT)
            socket?.broadcast = true
            socket?.soTimeout = 1000 // 1秒超时

            isRunning.set(true)

            // 启动接收线程
            startReceiver()

            Log.i(TAG, "UDP discovery started on port ${socket?.localPort}")
            promise.resolve("Discovery started")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start UDP discovery", e)
            promise.reject("START_ERROR", e.message, e)
        }
    }

    private fun stopDiscoveryInternal() {
        isRunning.set(false)
        socket?.close()
        socket = null
    }

    @ReactMethod
    fun stopDiscovery(promise: Promise) {
        try {
            stopDiscoveryInternal()
            Log.i(TAG, "UDP discovery stopped")
            promise.resolve("Discovery stopped")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to stop UDP discovery", e)
            promise.reject("STOP_ERROR", e.message, e)
        }
    }

    private fun startReceiver() {
        Thread {
            val buffer = ByteArray(65536)
            Log.i(TAG, "UDP receiver thread started")
            
            while (isRunning.get()) {
                try {
                    val packet = DatagramPacket(buffer, buffer.size)
                    Log.d(TAG, "Waiting for UDP packet...")
                    socket?.receive(packet)
                    
                    Log.i(TAG, "Received UDP packet from ${packet.address}:${packet.port}, length: ${packet.length}")
                    processReceivedPacket(packet)
                } catch (e: SocketTimeoutException) {
                    // 超时是正常的，继续循环
                    Log.d(TAG, "UDP receive timeout, continuing...")
                    continue
                } catch (e: Exception) {
                    if (isRunning.get()) {
                        Log.e(TAG, "Error receiving packet", e)
                    }
                }
            }
            Log.i(TAG, "UDP receiver thread stopped")
        }.start()
    }

    private fun processReceivedPacket(packet: DatagramPacket) {
        try {
            if (packet.length < 8) {
                Log.d(TAG, "Received short packet from ${packet.address}")
                return
            }

            val data = packet.data
            val buffer = ByteBuffer.wrap(data, 0, packet.length).order(ByteOrder.BIG_ENDIAN)
            
            // 检查魔数
            val magic = buffer.int
            if (magic != MAGIC) {
                Log.d(TAG, "Received packet with wrong magic: 0x${magic.toString(16)} from ${packet.address}")
                return
            }

            // 解析数据长度
            val dataLength = buffer.int
            if (packet.length < 8 + dataLength) {
                Log.d(TAG, "Received truncated packet from ${packet.address}")
                return
            }

            // 解析设备信息
            val deviceInfoBytes = ByteArray(dataLength)
            buffer.get(deviceInfoBytes)
            val deviceInfoJson = String(deviceInfoBytes, Charsets.UTF_8)
            
            val deviceInfo = JSONObject(deviceInfoJson)
            val deviceId = deviceInfo.getString("id")
            
            Log.i(TAG, "Received announcement from ${packet.address} for device $deviceId")

            // 发送事件到 React Native
            sendDeviceDiscoveredEvent(deviceInfo, packet.address)

        } catch (e: Exception) {
            Log.e(TAG, "Error processing received packet", e)
        }
    }

    private fun sendDeviceDiscoveredEvent(deviceInfo: JSONObject, sourceAddress: InetAddress) {
        try {
            val eventEmitter = reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            val eventData: WritableMap = Arguments.createMap().apply {
                putString("host", sourceAddress.hostAddress)
                putInt("port", deviceInfo.getInt("port"))
                putString("deviceName", deviceInfo.getString("name"))
                putString("deviceId", deviceInfo.getString("id"))
                putString("url", "https://${sourceAddress.hostAddress}:${deviceInfo.getInt("port")}")
                putBoolean("isHttps", true)
                putString("discoveryType", "udp")
            }
            eventEmitter.emit("onBabyTapMobileDiscovered", eventData)
            Log.d(TAG, "✅ UDP discovery event sent successfully")
        } catch (e: Exception) {
            Log.e(TAG, "❌ Failed to send UDP discovery event", e)
        }
    }
} 